﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Domain.Abstract;
using Pro260Website.Models;
using Domain.Entity;
using Pro260Website.Areas.Admin.Models;
using Domain.Concrete;
using Pro260Website.Infrastructure.Filters;
namespace Pro260Website.Areas.Admin.Controllers
{
    [Authorize(Roles="Admin")]
    public class GameController : Controller
    {
        public IGameRepository repository;
        public IPlatformRepository PlatRepo { get; set; }
        public EFDbContext Context { get; set; }
        public IMetaScoreRepository _metaRepository;
        public IVideoRepository repositoryVideo;

        public GameController(IGameRepository repository, IPlatformRepository platRepo, IMetaScoreRepository metaRepository, IVideoRepository videoRepository)
        {
            Context = EFDbContext.Instance;
            this.repository = repository;
            this.repository.Context = Context;
            PlatRepo = platRepo;
            PlatRepo.Context = Context;
            _metaRepository = metaRepository;
            _metaRepository.Context = Context;
            this.repositoryVideo = videoRepository;
        }
        public ActionResult Index(string searchFor="", int page = 1, int pageSize = 10)
        {
            var items = repository.Games;

            if (!string.IsNullOrWhiteSpace(searchFor))
            {
                items = items.Where(g => g.Name.ToLower().Contains(searchFor.ToLower()));
            }

            return View(new ListingViewModel<Game>
            {
                Items = items.OrderBy(g => g.Id).Skip((page - 1) * pageSize).Take(pageSize),
                PagingInfo = new PagingInfo
                {
                    CurrentPage = page,
                    ItemsPerPage = pageSize,
                    TotalItems = items.Count()
                }
            });
        }

        public ActionResult Edit(int id)
        {
            return View(repository.Games.SingleOrDefault(g => g.Id == id));
        }

        [HttpPost]
        [YoutubeLinkParse]
        public ActionResult Edit(Game entity, HttpPostedFileBase image, HttpPostedFileBase video)
        {
                Video vid = null;
                ViewBag.Message = "Your platform has been saved";
                if (image != null)
                {
                    var picture = new Picture()
                    {
                        ImageMimeType = image.ContentType,
                        ImageData = new byte[image.ContentLength]
                    };
                    image.InputStream.Read(picture.ImageData, 0, image.ContentLength);
                    entity.Pictures.Add(picture);
                    repository.Context.Pictures.Add(picture);
                }
                if (video != null)
                {
                    var nameOriginal = video.FileName;
                    var pathTemp = Path.Combine(Server.MapPath(""), nameOriginal);
                    var fileExtension = Path.GetExtension(pathTemp);
                    if (fileExtension.Equals(".swf") || fileExtension.Equals(".wmv"))
                    {
                        bool nameExists = false;
                        var fileName = string.Empty;

                        while (true)
                        {
                            nameExists = false;
                            fileName = GenerateID() + fileExtension;

                            foreach (var v in repositoryVideo.Videos)
                            {
                                if (v.VideoName != null)
                                {
                                    if (v.VideoName.Equals(fileName))
                                    {
                                        nameExists = true;
                                    }
                                }
                            }
                            if (!nameExists)
                            {
                                break;
                            }

                        }
                        if (!nameExists)
                        {
                            if (fileExtension.Equals(".swf") || fileExtension.Equals(".wmv"))
                            {
                                var path = Path.Combine(Server.MapPath("~/Content/Video"), fileName);
                                entity.FileName = fileName;
                                video.SaveAs(path);

                                vid = new Video()
                                {
                                    VideoName = fileName,
                                    OriginalName = nameOriginal,
                                    ExtensionType = fileExtension
                                };

                                repositoryVideo.SaveVideo(vid);
                            }
                        }
                    }
                }

                repository.Save(entity);
                return RedirectToAction("Index", "Game");
        }

        public ActionResult AddImage(int gameId)
        {
            return View(new GameImageViewModel()
            {
                GameId = gameId
            });
        }

        [HttpPost]
        public ActionResult AddImage(GameImageViewModel viewModel)
        {
            var entity = repository.FindById(viewModel.GameId);
            var image = viewModel.Image;
            var picture = new Picture()
            {
                ImageMimeType = image.ContentType,
                ImageData = new byte[image.ContentLength]
            };
            image.InputStream.Read(picture.ImageData, 0, image.ContentLength);
            entity.Pictures.Add(picture);
            repository.Context.Pictures.Add(picture);
            repository.Save(entity);
            return RedirectToAction("Index", "Game");
        }

        public ActionResult RemoveImage(int gameId)
        {
            return View(repository.FindById(gameId));
        }

        [HttpPost]
        public ActionResult RemoveImage(int Id, int? pictureId)
        {
            if (pictureId != null)
            {
                var game = repository.FindById(Id);
                game.Pictures.Remove(game.Pictures.FirstOrDefault(p => p.Id == pictureId.Value));
                repository.Context.Pictures.Remove(repository.Context.Pictures.FirstOrDefault(p => p.Id == pictureId.Value));
                repository.Save(game);
            }
            return RedirectToAction("RemoveImage", new { gameId = Id });
        }

        public ActionResult Delete(int id)
        {
            ViewBag.Message = "Your platform has been deleted";
            repository.Delete(repository.Games.SingleOrDefault(g => g.Id == id));
            return RedirectToAction("Index", "Game");
        }
        public ActionResult Create()
        {
            return View("Edit", new Game());
        }

        public ActionResult AddNews(int gameId)
        {
            var model = new GameNewsViewModel
            {
                GameId = gameId,
                Article = new GameNewsArticle
                {
                    PostedDate = DateTime.Now
                }
            };
            return View(model);
        }

        [HttpPost]
        public ActionResult AddNews(GameNewsViewModel model)
        {
            if (ModelState.IsValid)
            {
                
                var game = repository.FindById(model.GameId);
                game.Articles.Add(model.Article);
                repository.Save(game);
                return RedirectToAction("Index");
            }
            return View(model);
        }

        [HttpPost]
        public ActionResult AddPlatform(int gameId, int platformId)
        {
            if (ModelState.IsValid)
            {
                var game = repository.FindById(gameId);
                game.Platforms.Add(Context.Platforms.FirstOrDefault(p => p.PlatformID == platformId));
                repository.Save(game);
            }
            return RedirectToAction("Index");
        }

        [HttpPost]
        public ActionResult RemovePlatform(int gameId, int platformId)
        {
            if (ModelState.IsValid)
            {
                var game = repository.FindById(gameId);
                game.Platforms.Remove(Context.Platforms.FirstOrDefault(p => p.PlatformID == platformId));
                if (!game.Platforms.Any(g => g.Name == "PC"))
                {
                    game.SystemRequirements = null;
                }
                repository.Save(game);
            }
            return RedirectToAction("Index");
        }

        public ActionResult ShowAvailablePlatforms(int gameId)
        {
            var game = repository.FindById(gameId);
            var ids = game.Platforms.Select(p => p.PlatformID);
            var availablePlatforms = PlatRepo.Platforms.Where(p => !ids.Contains(p.PlatformID));
            if (availablePlatforms.Count() > 0)
                return PartialView(new GamePlatformViewModel
                {
                    GameId = game.Id,
                    AvailablePlatforms = availablePlatforms
                });
            else
                return null;
        }

        public ActionResult ShowCurrentPlatforms(int gameId)
        {
            var game = repository.FindById(gameId);
            var availablePlatforms = game.Platforms;
            if (availablePlatforms.Count() > 0)
                return PartialView(new GamePlatformViewModel
                {
                    GameId = game.Id,
                    AvailablePlatforms = availablePlatforms
                });
            else
                return null;
        }

        public ActionResult CreateMetaScore(int id)
        {
            return View(new MetaScore
            {
               GameId = id
            });
        }

        [HttpPost]
        public ActionResult SaveMetaScore(MetaScore metascore)
        {
             var game = this.repository.FindById(metascore.GameId);
             game.MetaScores.Add(metascore);
            this.repository.Save(game);

            _metaRepository.Save(metascore);
            return RedirectToAction("Index");
        }

        private string GenerateID()
        {
            Random random = new Random();
            string ID = "";
            for (int i = 0; i < 16; i++)
            {
                int num = random.Next(48, 58);
                int upper = random.Next(65, 91);
                int lower = random.Next(97, 123);

                int which = random.Next(3);
                if (which == 0)
                {
                    ID = ID + (char)num;
                }
                else if (which == 1)
                {
                    ID = ID + (char)upper;
                }
                else if (which == 2)
                {
                    ID = ID + (char)lower;
                }
            }

            return ID;
        }

    }
}
